在前一天的文章介紹了 Handshake 流程中協商 Connection ID 的過程,但是 Connection ID 是放在 Header 中以明碼傳輸,所以 QUIC 支援利用 Transport Parameters 的方式驗證每個端點在 Handshake 過程中選擇的 Connection ID,今天就來簡單介紹一下 QUIC 如何驗證 Connection ID。
首先來介紹一下 Transport Parameters 是什麼,如果讀過 RFC9000 會發現 Transport Parameters 是作為 TLS extension 存在的,主要是在 HandShake 流程中負責傳遞一些自己這端的配置給對方。
在前幾天 wireshark 的例子中,可以在 Client 端傳給 Server 的第一個 Initial packet 中的 CRYPTO frame 裡面找到 Extension: quic_transport_parameters
看到 Transport Parameters 的相關參數。
皆會觸發 TRANSPORT_PARAMETER_ERROR。
在之前的介紹中我們知道 Handshake 流程會透過 Initial packet 來進行交互,如下圖所示
在每個終端 (Client/Server) 發送 Initial packet 時,必須要在 header 中的 Source Connection ID
填入自己這端生成的 Connection ID,同時也要在 Transport Parameter 的 initial_source_connection_id
欄位填入相同的值。
當 Server 收到 Client 發送的 Initial packet 時,header 的 Destination Connection ID
欄位是 Client 端隨機生成的一個臨時值,我們暫且把它稱為 dtmp,Server 必須要把這個臨時的 dtmp 填入回傳的 Tranport Parameter 的 original_destination_connection_id
欄位,然後把自己這端真正的 Connection ID 放到 header 的 Destination Connection ID
欄位。
下面這張圖是我從 wireshark 截圖下來的,可能有點不清楚,有興趣的可以自己觀察看看, Server 收到的臨時 DCID 的確在範例中會被填入回傳的 original_destination_connection_id
欄位。
在 Handshake 期間,建立連線雙方都必須要比對 Transport Parameter 中的值與填入 header 的值是相同的,這可以確保惡意的攻擊者,無法在握手過程中,將竄改過的封包填入自己的 Connection ID,影響後續的 Connection ID 選擇。
如果檢測到封包的 initial_source_connection_id
或者來自 Server 端的 original_destination_connection_id
不符合或者缺失時,必須要觸發 TRANSPORT_PARAMETER_ERROR。